package main.java.single;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

// 懒汉式单例
public class LazyMan03 {
    //构造器私有
    private LazyMan03(){
        synchronized (LazyMan03.class){
            if(lazyMan != null){
                throw new RuntimeException("不要试图使用反射破坏异常");
            }
        }
    }

    private volatile static LazyMan03 lazyMan;
    //多线程情况下 会存在问题 解决了多行程下的问题
    public static LazyMan03 getInstance(){
        if(lazyMan == null){
            synchronized (LazyMan03.class){
                if (lazyMan == null){
                    //还有问题 不是原子性操作
                    lazyMan = new LazyMan03();
                    /**
                     * 1.分配内存空间
                     * 2.执行构造方法，初始化对象
                     * 3.把这个对象指向这个空间
                     *
                     * 但是如果不能保证原子性 有可能出现132的情况 此时lazyMan还没有完成构造 返回的式一个null的lazyMan
                     * 为了解决这个问题 volatile
                     */
                }
            }
        }
        return lazyMan;
    }

    //反射
    // 这里出现问题是因为先执行了A步骤 但是如果不执行A步骤 两边都用反射来创建 还是会有问题
    public static void main(String[] args) throws Exception {
//        LazyMan03 instance2 = LazyMan03.getInstance();//A步骤
//        Field lazyMan = instance2.getClass().getDeclaredField("lazyMan");
//        lazyMan.set(instance2,null);
        //通过反射来破坏单例
        Constructor<LazyMan03> declaredConstructor = LazyMan03.class.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);
        LazyMan03 instance = declaredConstructor.newInstance();
        LazyMan03 instance2 = declaredConstructor.newInstance();
        System.out.println(instance);
        System.out.println(instance2);

    }
}
